home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / comm / bbs / s342q07.lha / netcall.c < prev    next >
C/C++ Source or Header  |  1995-07-09  |  31KB  |  1,218 lines

  1. /*
  2. *       netcall.c
  3. *
  4. * Networking call functions.
  5. */
  6. /*
  7. *       history
  8. *
  9. * 86Aug20 HAW  History not maintained due to space problems.
  10. */
  11. #include "ctdl.h"
  12. #include "math.h"
  13. /*
  14. *       contents
  15. *
  16. */
  17. char                    inReceive;
  18. NetInfo     NetStyle;
  19. extern char   RecMassTransfer;
  20. extern char             *SR_Sent;
  21. extern char             *pollCall;
  22. extern FILE             *netMisc;
  23. extern FILE             *netLog;
  24. extern AN_UNSIGNED      RecBuf[SECTSIZE + 5];
  25. extern int              counter;
  26. extern int              callSlot;
  27. extern label            callerName, callerId;
  28. char                    checkNegMail;
  29. extern char             processMail;
  30. extern char   MassTransferSent;
  31. char             normId(), getNetMessage();
  32. AN_UNSIGNED      inp();
  33. extern CONFIG    cfg;            /* Lots an lots of variables    */
  34. extern logBuffer logBuf;         /* Person buffer                */
  35. extern logBuffer logTmp;         /* Person buffer                */
  36. extern aRoom     roomBuf;        /* Room buffer                  */
  37. extern rTable    *roomTab;
  38. extern PROTO_TABLE Table[];
  39. extern int TransProtocol;
  40. extern MessageBuffer   msgBuf;
  41. extern NetBuffer netBuf, netTemp;
  42. extern NetTable  *netTab;
  43. /* extern SListBase FwdAliasii; */
  44. extern int       thisNet;
  45. extern char      onConsole;
  46. extern char      loggedIn;       /* Is we logged in?             */
  47. extern char      outFlag;        /* Output flag                  */
  48. extern char      haveCarrier;    /* Do we still got carrier?     */
  49. extern char      modStat;        /* Needed so we don't die       */
  50. extern char      TrError;
  51. extern int       thisRoom;
  52. extern char      netDebug;
  53. extern char      logNetResults;
  54. extern char  *DomainFlags;
  55. extern long ByteCount, EncCount;
  56. char *chMailTemplate = "chkMail.$$$";
  57. extern long  char_in, char_out; /* send/recieve character counts*/
  58. long start_time;                /* total time of session */
  59. /*
  60. * caller()
  61. *
  62. * This function is called when we've been called and have to handle the
  63. * caller.  We have to stabilize the call and then manage all requests
  64. * the caller makes of us.
  65. */
  66. void caller()
  67.   {
  68.   ITL_InitCall();             /* initialize the ITL layer */
  69.   RecMassTransfer = FALSE;
  70.   memset(SR_Sent, 0, SHARED_ROOMS);
  71.   inReceive = FALSE;
  72.   processMail = FALSE;
  73.   checkNegMail = FALSE;
  74.   SpecialMessage("Status:Net Carrier");
  75.   if( logNetResults && netDebug )splitF(netLog, "Have Carrier\n");
  76.   caller_stabilize();
  77.   if (!haveCarrier) return ;  /* Abort */
  78.   if( logNetResults )splitF(netLog, "Stabilized\n");
  79.   SpecialMessage("Status:Net Session");
  80.   char_in = char_out = 0;
  81.   start_time = Set_Timer(0);
  82.   sendId();
  83.   if (!haveCarrier) return ;  /* Abort */
  84.   if (!netBuf.nbflags.MassTransfer)
  85.   ITL_optimize(TRUE);   /* try for better protocol */
  86.   sendStuff(FALSE, TRUE);
  87.   startTimer(WORK_TIMER);
  88.   while (gotCarrier() && chkTimeSince(WORK_TIMER) < 10) ;
  89.   killConnection();
  90.   if( logNetResults )splitF(netLog, "\nFinished with %s @%s\n", netBuf.netName, Current_Time());
  91.   Compute_Data(netBuf.netName);
  92.   doResults();
  93.   SpecialMessage("Status:Net Completed");
  94.  
  95.   }
  96. /*
  97. * sendStuff()
  98. *
  99. * This function handles being the sender of information (sending role).
  100. */
  101. void sendStuff(char reversed, char SureDoIt)
  102.   {
  103.   extern int RouteToDirect;
  104.   if (SureDoIt && callSlot != ERROR)
  105.     {
  106.     MassTransferSent = FALSE;
  107.     SendPwd();
  108.     if (!haveCarrier) return ;  /* Abort */
  109.     if (netBuf.nbflags.HasRouted)    RouteOut();
  110.     if (!haveCarrier) return ;  /* Abort */
  111.     if (!netBuf.nbflags.Stadel) DomainOut(FALSE);
  112.     if (!haveCarrier) return ;  /* Abort */
  113.     if (netBuf.nbflags.normal_mail ||
  114.     RouteToDirect != -1 ||
  115.     (netBuf.nbflags.Stadel && DomainFlags[thisNet]))
  116.       {
  117.       sendMail();
  118.       if (!haveCarrier) return ;  /* Abort */
  119.       checkMail();
  120.  
  121.       }
  122.     if (!haveCarrier) return ;  /* Abort */
  123.     if (!HasPriorityMail(thisNet))
  124.       {
  125.       if (netBuf.nbflags.room_files)
  126.       askFiles();
  127.       if (!haveCarrier) return ;  /* Abort */
  128.       sendSharedRooms();
  129.       if (!haveCarrier) return ;  /* Abort */
  130.       if (netBuf.nbflags.send_files)
  131.       doSendFiles();
  132.       if (!haveCarrier) return ;  /* Abort */
  133.       roleReversal(reversed);
  134.  
  135.       }
  136.  
  137.     }
  138.   sendHangUp();
  139.   pollCall[thisNet]--;        /* Don't set polled flag unless stable call */
  140.  
  141.   }
  142. /*
  143. * SendPwd()
  144. *
  145. * This function sends the system password if necessary.
  146. */
  147. void SendPwd()
  148.   {
  149.   struct cmd_data cmds;
  150.   if (netBuf.TheirPwd[0] != 0)
  151.     {
  152.     /* only send if need to -- gets */
  153.     zero_struct(cmds);              /* us around a bug in pre net 1.10*/
  154.     strCpy(cmds.fields[0], netBuf.TheirPwd);        /* versions     */
  155.     cmds.command = SYS_NET_PWD;
  156.     sendNetCommand(&cmds, "system pwd");
  157.  
  158.     }
  159.  
  160.   }
  161. /*
  162. * roleReversal()
  163. *
  164. * This function handles the role reversal request.
  165. */
  166. void roleReversal(char reversed)
  167.   {
  168.   struct cmd_data cmds;
  169.   if (reversed) return ;
  170.   if (!netBuf.nbflags.local && !netBuf.nbflags.spine) return ;
  171.   if( logNetResults && netDebug )splitF(netLog, "Reversing roles\n");
  172.   zero_struct(cmds);
  173.   cmds.command = ROLE_REVERSAL;
  174.   if (!sendNetCommand(&cmds, "role reversal"))
  175.   return;
  176.   rcvStuff(TRUE);
  177.   pause(50);   /* wait a second */
  178.   if (gotCarrier())
  179.   reply(GOOD, "");/* this replies GOOD to the HANGUP terminating the */
  180.   /* role reversal.  NOTE: STadel doesn't follow the */
  181.   /* spec in this regard - it just dumps carrier     */
  182.  
  183.   }
  184. /*
  185. * caller_stabilize()
  186. *
  187. * This function tries to stabilize the call -- baud is already set.
  188. */
  189. void caller_stabilize()
  190.   {
  191.   int tries, x1, x2, x3;
  192.   extern char hst;
  193.   /* regrettable initialization */
  194.   for (tries = 0; tries < SHARED_ROOMS; tries++) resetNeedsProcessing(tries);
  195.   putNet(thisNet, &netBuf);
  196.   pause(50);                                  /* delay for a little bit */
  197.   while (MIReady())   inp();                  /* Clear garbage        */
  198.   startTimer(USER_TIMER);                     /* this is safe */
  199.   x1 = x2 = x3 = 0;
  200.   for (tries = 0; (chkTimeSince(USER_TIMER) < 20l || tries < 40) &&
  201.   gotCarrier() ; tries++)
  202.     {
  203.     outMod(7);
  204.     outMod(13);
  205.     outMod(69);
  206.     for (  startTimer(WORK_TIMER);
  207.     chkTimeSince(WORK_TIMER) < 2l && !MIReady();) ;
  208.     if (MIReady())
  209.       {
  210.       x1 = receive(2);
  211.       x2 = receive(2);
  212.       if (x2 != ERROR) x3 = receive(2);
  213.       if (x1 == 248 && x2 == 242 && x3 == 186)
  214.         {
  215.         outMod(ACK);
  216.         if (cfg.BoolFlags.debug) splitF(netLog, "ACKing, Call stabilized\n");
  217.         /* ok, we've seen at high speed some overrun problems, so ... */
  218.         do
  219.           {
  220.           x1 = receive(2);
  221.  
  222.           }
  223.         while (x1 == 248 || x1 == 242 || x1 == 186);
  224.         ModemPushBack(x1);
  225.         return;
  226.  
  227.         }
  228.       else
  229.         {
  230.         if ( ( x1 == 242 || x1 == 186 || x1 == 248 )
  231.         || ( x2 == 242 || x2 == 186 || x2 == 248 )
  232.         || ( x3 == 242 || x3 == 186 || x3 == 248 ) )  /* all combinations */
  233.           {
  234.           /* real close, so let's catch our breath */
  235.           if (cfg.BoolFlags.debug) splitF(netLog, "..ReSynch\n");
  236.           while (receive(1) != ERROR) ;
  237.  
  238.           };
  239.  
  240.         }
  241.  
  242.       }
  243.     else
  244.       {
  245.       if( cfg.BoolFlags.debug)splitF(netLog,"No response from net tickle\n");
  246.       tries ++;  /* if we get nothing back, don't try as much, try half the number of times */
  247.  
  248.       }
  249.  
  250.     }
  251.   if( logNetResults && netDebug )splitF(netLog, "Call not stabilized:tries=%d \n",tries);
  252.   killConnection();
  253.  
  254.   }
  255. /*
  256. * sendId()
  257. *
  258. * This function sends ID to the receiver.
  259. */
  260. void sendId()
  261.   {
  262.   if (!ITL_Send(STARTUP))
  263.     {
  264.     no_good("Couldn't transfer ID to %s at startup!", TRUE);
  265.     return;
  266.  
  267.     }
  268.   mTrPrintf("%s", cfg.codeBuf + cfg.nodeId  );
  269.   mTrPrintf("%s", cfg.codeBuf + cfg.nodeName);
  270.   if (!ITL_Send(FINISH))
  271.     {
  272.     no_good("Couldn't transfer ID to %s at finish!", TRUE);
  273.     return;
  274.  
  275.     }
  276.  
  277.   }
  278. /*
  279. * sendMail()
  280. *
  281. * This function sends normal mail to receiver.
  282. */
  283. void sendMail()
  284.   {
  285.   struct cmd_data cmds;
  286.   int             nor_mail;
  287.   extern int      RouteToDirect;
  288.   if (!gotCarrier())
  289.     {
  290.     modStat = haveCarrier = FALSE;
  291.     return ;
  292.  
  293.     }
  294.   if( logNetResults )splitF(netLog, "Sending Mail ");
  295.   zero_struct(cmds);
  296.   cmds.command = NORMAL_MAIL;
  297.   if (!sendNetCommand(&cmds, "normal mail"))
  298.   return;
  299.   if (!ITL_SendMessages())
  300.     {
  301.     no_good("Couldn't start Mail transfer to %s!", TRUE);
  302.     killConnection();
  303.     return;
  304.  
  305.     }
  306.   nor_mail = s_m_n();            /* Send normal mail     */
  307.   if (gotCarrier())
  308.   nor_mail += SendRoutedAsLocal();
  309.   if (gotCarrier() && netBuf.nbflags.Stadel)
  310.   nor_mail += DomainOut(TRUE);
  311.   ITL_StopSendMessages();
  312.   RouteToDirect = -1;         /* This is just in case */
  313.   if (gotCarrier())
  314.     {
  315.     if( logNetResults )splitF(netLog, "(%d) (%ld => %ld bytes)\n",nor_mail,EncCount,ByteCount);
  316.     netBuf.nbflags.normal_mail = FALSE;
  317.  
  318.     }
  319.  
  320.   }
  321. /*
  322. * checkMail()
  323. *
  324. * This function handles negative acknowledgement on netMail.
  325. */
  326. void checkMail()
  327.   {
  328.   struct cmd_data cmds;
  329.   SYS_FILE fileNm;
  330.   extern char *WRITE_ANY;
  331.   if (!gotCarrier())
  332.     {
  333.     return;
  334.  
  335.     }
  336.   if( logNetResults && netDebug )splitF(netLog, "Check mail\n");
  337.   makeSysName(fileNm, chMailTemplate, &cfg.netArea);
  338.   zero_struct(cmds);
  339.   cmds.command = CHECK_MAIL;
  340.   if (!sendNetCommand(&cmds, "check mail"))
  341.     {
  342.     return;
  343.  
  344.     }
  345.   if (ITL_Receive(fileNm, FALSE, TRUE, putFLChar, fclose) == ITL_SUCCESS)
  346.   checkNegMail = TRUE;        /* Call readNegMail() later */
  347.  
  348.   }
  349. /*
  350. * readNegMail()
  351. *
  352. * This function reads and processes negative acks.
  353. */
  354. void readNegMail(char talk)
  355.   {
  356.   label author, target, context;
  357.   int whatLog;
  358.   int  sigChar;
  359.   SYS_FILE fileNm;
  360.   extern char *READ_ANY;
  361.   makeSysName(fileNm, chMailTemplate, &cfg.netArea);
  362.   if ((netMisc = safeopen(fileNm, READ_ANY)) == NULL)
  363.     {
  364.     if (talk) no_good("Couldn't open negative ack file from %s.", FALSE);
  365.     return ;
  366.  
  367.     }
  368.   getRoom(MAILROOM);
  369.   sigChar = fgetc(netMisc);
  370.   while (sigChar != NO_ERROR && sigChar != EOF && sigChar != EOF)
  371.     {
  372.     ZeroMsgBuffer(&msgBuf);
  373.     strCpy(msgBuf.mbauth, "Citadel");
  374.     getMsgStr(getNetChar, author, NAMESIZE);
  375.     getMsgStr(getNetChar, target, NAMESIZE);
  376.     getMsgStr(getNetChar, context, NAMESIZE);
  377.     switch (sigChar)
  378.       {
  379.       case NO_RECIPIENT:
  380.       strCpy(msgBuf.mbto, author);
  381.       if ((whatLog = PersonExists(author)) >= 0 &&
  382.       whatLog < cfg.MAXLOGTAB)
  383.         {
  384.         sPrintf(msgBuf.mbtext,
  385.         "Your netMail to '%s' (%s) failed because there is no such recipient on %s.",
  386.         target, context, callerName);
  387.         putMessage(&logBuf);
  388.         break;
  389.  
  390.         }
  391.       case UNKNOWN:
  392.       ZeroMsgBuffer(&msgBuf);
  393.       sPrintf(msgBuf.mbtext,
  394.       "Unknown problems with netMail: author=-%s-, target=-%s-, context=-%s-.  System was %s.",
  395.       author, target, context, netBuf.netName);
  396.       netResult(msgBuf.mbtext);
  397.       break;
  398.       case BAD_FORM:
  399.       sPrintf(msgBuf.mbtext, "Bad netMail sent to %s.", callerName);
  400.       netResult(msgBuf.mbtext);
  401.       break;
  402.       default:
  403.       sPrintf(msgBuf.mbtext, "Bad sigChar=%d.", sigChar);
  404.       netResult(msgBuf.mbtext);
  405.       break;
  406.  
  407.       }
  408.     sigChar = fgetc(netMisc);
  409.  
  410.     }
  411.   fclose(netMisc);
  412.   if (cfg.BoolFlags.debug)
  413.     {
  414.      splitF(netLog,
  415.     "problems with netMail: author=-%s-, target=-%s-, context=-%s-.  System was %s.",
  416.       author, target, context, netBuf.netName);
  417.     };
  418.   unlink(fileNm);
  419.  
  420.   }
  421. /*
  422. * sendSharedRooms()
  423. *
  424. * This sends all shared rooms to receiver.
  425. */
  426. static int SendRoom(SharedRoom *room, int system, int index, int roomslot,void *d);
  427. void sendSharedRooms()
  428.   {
  429.   SendFastTransfer();
  430.   EachSharedRoom(thisNet, SendRoom, SendVirtualRoom, NULL);
  431.  
  432.   }
  433. /*
  434. * EachSharedRoom()
  435. *
  436. * This does something for each shared room.
  437. */
  438. void EachSharedRoom(int system,
  439. int (*func)(SharedRoom *room, int system, int index, int roomslot, void *d),
  440. int (*virtfunc)(VirtualRoom *room, int sys, int index, int which, void *d),
  441. void *data)
  442.   {
  443.   int rover;
  444.   if (!netTab[system].ntflags.in_use) return;
  445.   if (func != NULL)
  446.     {
  447.     for (rover = 0; rover < SHARED_ROOMS; rover++)
  448.       {
  449.       if (isSharedRoom(system, rover) && roomValidate(system, rover))
  450.         {
  451.         if ((*func)(netTab[system].netTRooms + rover, system,
  452.         rover, netTabRoomSlot(system, rover), data) == ERROR)
  453.         return;
  454.  
  455.         }
  456.  
  457.       }
  458.  
  459.     }
  460.   if (virtfunc != NULL) DoVirtuals(system, virtfunc, data);
  461.  
  462.   }
  463. /*
  464. * Addressing()
  465. *
  466. * This function is responsible for deciding what sort of addressing or routing
  467. * flags should be checked for, and if the room should be sent if we are in
  468. * a network session.
  469. */
  470. void Addressing(int system, int index, char *commnd, char **send1, char **send2,
  471. char **send3, char **name, char *doit)
  472.   {
  473.   extern char *R_SH_MARK, *NON_LOC_NET, *LOC_NET;
  474.   /*
  475.   * This is more than just a trivial efficiency.  This routine can be called
  476.   * indirectly by the room editing functions.  If this happens then the
  477.   * getRoom() call would overwrite the roomBuf being used for editing.
  478.   * Therefore, we can only read in roomBuf if we don't have the right one
  479.   * in place, otherwise we lose what we just changed.
  480.   */
  481.   if (cfg.BoolFlags.debug)
  482.    splitF(netLog, "Before: Addressing(system:%d, index:%d, commnd:%d, send1:%s, send2:%d, send3:%d, name3:%s, doit:%s)\n",
  483.                                         system, index,   (int)*commnd
  484.    , (*send1 ? *send1 : "NULL"), (int)*(*send2)   , (int)*(*send3)
  485.    , (*name  ? *name  : "NULL"), (*doit  ? "TRUE" : "FALSE"));
  486.  
  487.   if (thisRoom != netTabRoomSlot(system, index))
  488.   getRoom(netTabRoomSlot(system, index));
  489.   *doit = TRUE;
  490.   *send1 = R_SH_MARK;
  491.   *send2 = *send3 = "guh";
  492.   switch (roomBuf.rbShareType)
  493.     {
  494.     case PEON:
  495.     *commnd = NET_ROOM;
  496.     *name = "Peon";
  497.     break;
  498.     case REG_HOST:          /* obsolete */
  499.     case BACKBONE:
  500.     switch (GetMode(netTab[system].netTRooms[index].mode))
  501.       {
  502.       case PEON:
  503.       *commnd = NET_ROOM;
  504.       *send2 = NON_LOC_NET;
  505.       *name = "Peon";
  506.       break;
  507.       case ACTIVE_BACKBONE:
  508.       case REG_HOST:
  509.       if (netTab[system].ntflags.local)
  510.       *commnd = NET_ROOM;
  511.       else
  512.       *commnd = NET_ROUTE_ROOM;
  513.       *send2 = NON_LOC_NET;
  514.       *send3 = LOC_NET;
  515.       *name = "Backbone - Active";
  516.       break;
  517.       case PASS_BACKBONE:
  518.       if (!netTab[system].ntflags.local && !inReceive) *doit = FALSE;
  519.       else if (netTab[system].ntflags.local)
  520.       *commnd = NET_ROOM;
  521.       else
  522.       *commnd = NET_ROUTE_ROOM;
  523.       *send2 = NON_LOC_NET;
  524.       *send3 = LOC_NET;
  525.       *name = "Backbone - Passive";
  526.       break;
  527.       default: crashout("shared rooms: #2");
  528.  
  529.       }
  530.     break;
  531.     default: crashout("shared rooms: #1");
  532.  
  533.     }
  534.   if (cfg.BoolFlags.debug)
  535.    splitF(netLog, "After: Addressing(system:%d, index:%d, commnd:%d, send1:%s. send2:%d, send3:%d, name3:%s, doit:%s)\n",
  536.    system, index, (int)commnd
  537.    , (*send1 ? *send1 : "NULL"), (int)*(*send2), (int)*(*send3)
  538.    , (*name  ? *name  : "NULL"), (*doit  ? "TRUE" : "FALSE"));
  539.  
  540.   }
  541. /*
  542. * SendRoom()
  543. *
  544. * Sends a room to the receiving system during netting.  It returns ERROR if
  545. * carrier etc is lost.
  546. */
  547. static int SendRoom(SharedRoom *room, int system, int index, int roomslot,
  548. void *d)
  549.   {
  550.   char cmd;
  551.   char doit, *s1, *s2, *s3, *name;
  552.   if (cfg.BoolFlags.debug)
  553.    splitF(netLog, "SendRoom(ShareRoom:%08.8X, system:%ld, index:%d, roomslot:%d d:%08.8X)\n",
  554.    room, system, index, roomslot, d);
  555.   if (!gotCarrier())
  556.     {
  557.     modStat = haveCarrier = FALSE;
  558.     return ERROR;
  559.  
  560.     }
  561.   Addressing(system, index, &cmd, &s1, &s2, &s3, &name, &doit);
  562.   if (doit && SR_Sent[index] != 1 &&
  563.   (roomTab[roomslot].rtlastNet >  netBuf.netRooms[index].lastMess ||
  564.   GetFA(room->mode) ||
  565.   (roomTab[roomslot].rtShareType == BACKBONE &&
  566.   GetMode(room->mode) != PEON &&  !netBuf.nbflags.local))
  567.   )
  568.     {
  569.     /**
  570.     if (cfg.BoolFlags.debug)
  571.     splitF(netLog, "Why: %s && %d[%d] && ( %ld > %ld || %d || ( %s BACKBONE && %s PEON && %s LOCAL))\n",
  572.     (doit ? "TRUE":"FALSE"), SR_Sent[index],index,
  573.     roomTab[roomslot].rtlastNet,netBuf.netRooms[index].lastMess,GetFA(room->mode),
  574.     (roomTab[roomslot].rtShareType == BACKBONE ? "" : "Not"),
  575.     (GetMode(room->mode) != PEON ? "Not" : ""),
  576.     (netBuf.nbflags.local ? "" : "NOT"));
  577.     **/
  578.     ITL_optimize(TRUE);
  579.     findAndSend((RecMassTransfer || chkNeedsProcessing(index)) ?
  580.     NET_ROOM : cmd, s1, s2, s3, index,
  581.     RoomSend, roomTab[roomslot].rtname, RoomReceive);
  582.  
  583.     }
  584.   return TRUE;
  585.  
  586.   }
  587. /*
  588. * findAndSend()
  589. *
  590. * This function manages sending a room (virtual or normal) to the receiver,
  591. * handling both normal and route rooms, via function pointers.
  592. */
  593. void  findAndSend(int commnd, char *send1, char *send2, char *send3, int rover,
  594. int (*MsgSender)(int r, char *d1, char *d2, char *d3),
  595. label roomName, int (*MsgReceiver)(int r, char y))
  596.   {
  597.   struct cmd_data cmds;
  598.   extern MessageBuffer tempMess;
  599.   int  tempcount;
  600.   extern char *netRoomTemplate, *WRITE_ANY;
  601.   if (!gotCarrier()) return;
  602.   zero_struct(cmds);
  603.   cmds.command = commnd;
  604.   strCpy(cmds.fields[0], roomName);
  605.   if (commnd != ERROR)
  606.   if (!sendNetCommand(&cmds, "shared rooms"))
  607.     {
  608.     if (commnd == NET_ROUTE_ROOM)
  609.       {
  610.       findAndSend(NET_ROOM, send1, send2, send3, rover, MsgSender,
  611.       roomName, MsgReceiver); /* time to recurse */
  612.       return ;
  613.  
  614.       }
  615.     else
  616.       {
  617.       sPrintf(tempMess.mbtext, "%%s reports: %s (%s) commnd=%d", RecBuf+1,
  618.       roomName,commnd);
  619.       no_good(tempMess.mbtext, FALSE);
  620.       return ;
  621.  
  622.       }
  623.  
  624.     }
  625.   if (!ITL_SendMessages())
  626.     {
  627.     no_good("Couldn't start WC for room sharing: %s",
  628.     FALSE);
  629.     return;
  630.  
  631.     }
  632.   tempcount = (*MsgSender)(rover, send1, send2, send3);
  633.   ITL_StopSendMessages();
  634.   if( logNetResults && netDebug )
  635.     {
  636.     if( EncCount > 0)
  637.       splitF(netLog, "(%d) (%ld => %ld bytes)\n", tempcount, EncCount, ByteCount);
  638.     else splitF(netLog,"\n");
  639.     };
  640.   if (commnd == NET_ROUTE_ROOM)
  641.     {
  642.     (*MsgReceiver)(rover, FALSE);
  643.  
  644.     }
  645.  
  646.   }
  647. /*
  648. * RoomReceive()
  649. *
  650. * This function receives messages for a room.
  651. */
  652. int RoomReceive(int rover, char ReplyFirst)
  653.   {
  654.   recNetMessages(rover, roomBuf.rbname, netRoomSlot(rover), FALSE);
  655.   return 0;
  656.  
  657.   }
  658. /*
  659. * RoomSend()
  660. *
  661. * This function sends messages for a room.
  662. */
  663. int RoomSend(int rover, char *send1, char *send2, char *send3)
  664.   {
  665.   extern char PrTransmit;
  666.   char work[10];
  667.   int MsgCount = 0;
  668.   if( logNetResults && netDebug )splitF(netLog, "Sending %s ", roomBuf.rbname);
  669.   zero_struct(NetStyle);
  670.   NetStyle.addr1 = send1;
  671.   NetStyle.addr2 = send2;
  672.   NetStyle.addr3 = send3;
  673.   if (GetFA(netBuf.netRooms[rover].mode))
  674.     {
  675.     sPrintf(work, CACHE_END_NAME, netRoomSlot(rover));
  676.     if (SendPrepAsNormal(work, &MsgCount))
  677.     UnSetFA(netBuf.netRooms[rover].mode);
  678.  
  679.     }
  680.   NetStyle.sendfunc = sendITLchar;
  681.   /*   PrTransmit = FALSE; */
  682.   MsgCount += showMessages(NEWoNLY, FALSE, netBuf.netRooms[rover].lastMess,
  683.   NetRoute);
  684.   if (TrError == TRAN_SUCCESS)
  685.     {
  686.     SetHighValues(rover);
  687.     SR_Sent[rover] = 1;
  688.  
  689.     }
  690.   else
  691.     {
  692.     MsgCount = 0;
  693.  
  694.     }
  695.   return MsgCount;
  696.  
  697.   }
  698. /*
  699. * SetHighValues()
  700. *
  701. * This function sets the high message sent for a normal shared room after a
  702. * successful net session has (apparently) taken place.
  703. */
  704. void SetHighValues(int rover)
  705.   {
  706.   if (NetStyle.HiSent == 0l)
  707.     {
  708.     NetStyle.HiSent =
  709.     max(netBuf.netRooms[rover].lastMess,roomTab[thisRoom].rtlastMessage);
  710.  
  711.     }
  712.   netBuf.netRooms[rover].lastMess = NetStyle.HiSent;
  713.   netTab[thisNet].netTRooms[rover].lastMess = NetStyle.HiSent;
  714.  
  715.   }
  716. /*
  717. * SendPrepAsNormal()
  718. *
  719. * This function sends files prepared for cache sending as normal message files,
  720. * instead.
  721. */
  722. char SendPrepAsNormal(char *work, int *MsgCount)
  723.   {
  724.   char tempNm[3*NAMESIZE];
  725.   NetCacheName(tempNm, thisNet, work);
  726.   if ((netMisc = safeopen(tempNm, READ_ANY)) != NULL)
  727.     {
  728.     while (getMessage(getNetChar, TRUE, TRUE, TRUE))
  729.       {
  730.       (*MsgCount)++;
  731.       prNetStyle(0, sendITLchar, FALSE, "");
  732.  
  733.       }
  734.     fclose(netMisc);
  735.  
  736.     }
  737.   if (gotCarrier())
  738.     {
  739.     unlink(tempNm);
  740.     return TRUE;
  741.  
  742.     }
  743.   return FALSE;
  744.  
  745.   }
  746. /*
  747. * NetRoute()
  748. *
  749. * This is a worker function, returns TRUE if message sent.
  750. */
  751. char NetRoute(int status)
  752.   {
  753.   long temp;
  754.   if ((strncmp(msgBuf.mbaddr, NetStyle.addr1, strLen(NetStyle.addr1))
  755.   == SAMESTRING  ||
  756.   strncmp(msgBuf.mbaddr, NetStyle.addr2, strLen(NetStyle.addr2))
  757.   == SAMESTRING  ||
  758.   strncmp(msgBuf.mbaddr, NetStyle.addr3, strLen(NetStyle.addr3))
  759.   == SAMESTRING) &&
  760.   RoutePath(LOC_NET, msgBuf.mbaddr)     != thisNet       &&
  761.   RoutePath(NON_LOC_NET, msgBuf.mbaddr) != thisNet)
  762.     {
  763.     prNetStyle(FALSE, NetStyle.sendfunc, TRUE, "");
  764.     temp = atol(msgBuf.mbId);
  765.     NetStyle.HiSent = max(NetStyle.HiSent,temp);
  766.     return TRUE;
  767.  
  768.     }
  769.   return FALSE;
  770.  
  771.   }
  772. /*
  773. * RoutePath()
  774. *
  775. * This function returns the number of the node that routed this msg to here.
  776. * If the msg was not routed in from a BackBone, then return ERROR, which will
  777. * never match another node's #.
  778. *
  779. * 88Oct13: Now simply check for msg origin, assume if one exists that it
  780. * should be checked.  Don't remember why it is restricted to only
  781. * BACKBONE-routed msgs.  Doesn't seem necessary.
  782. */
  783. int RoutePath(char *rp, char *str)
  784.   {
  785.   if (strncmp(rp, str, strLen(rp)) == SAMESTRING)
  786.     {
  787.     if (strLen(str) != strLen(rp)) /* prevent return of 0 */
  788.     return atoi(str + 2);
  789.  
  790.     }
  791.   return ERROR;
  792.  
  793.   }
  794. /*
  795. * doSendFiles()
  796. *
  797. * This function will send files to a victim.
  798. */
  799. void doSendFiles()
  800.   {
  801.   extern char       *READ_ANY;
  802.   struct   fl_send  theFiles;
  803.   SYS_FILE          sdFile;
  804.   char              temp[8];
  805.   FILE              *fd;
  806.   ITL_optimize(FALSE);    /* try for better protocol */
  807.   sPrintf(temp, "%d.sfl", thisNet);
  808.   makeSysName(sdFile, temp, &cfg.netArea);
  809.   if ((fd = safeopen(sdFile, READ_ANY)) == NULL)
  810.     {
  811.     sPrintf(msgBuf.mbtext, "Couldn't open send file %s for %s!",
  812.     sdFile,netBuf.netName);
  813.     netResult(msgBuf.mbtext);
  814.     netBuf.nbflags.send_files = FALSE;
  815.  
  816.     }
  817.   else
  818.     {
  819.     while (getSLNet(theFiles, fd) && haveCarrier)
  820.       {
  821.       sysSendFiles(&theFiles);
  822.  
  823.       }
  824.     fclose(fd);
  825.     if (haveCarrier)
  826.       {
  827.       /* if no carrier, was an error during transmit */
  828.       unlink(sdFile);
  829.       netBuf.nbflags.send_files = FALSE;
  830.  
  831.       }
  832.  
  833.     }
  834.  
  835.   }
  836. /*
  837. * netSendFile()
  838. *
  839. * This function will send a file to another system via net.
  840. */
  841. void netSendFile(DirEntry *fn)
  842.   {
  843.   extern char     *READ_ANY;
  844.   struct cmd_data cmds;
  845.   char            mess[140];
  846.   if (!gotCarrier()) return ;
  847.   if( logNetResults && netDebug )splitF(netLog, "Send File: %s\n", fn->unambig);
  848.   zero_struct(cmds);
  849.   cmds.command = SEND_FILE;
  850.   strCpy(cmds.fields[0], fn->unambig);
  851.   sPrintf(cmds.fields[1], "%ld", (fn->FileSize + SECTSIZE - 1) / SECTSIZE);
  852.   sPrintf(cmds.fields[2], "%ld", fn->FileSize);
  853.   if (!sendNetCommand(&cmds, "send file"))
  854.     {
  855.     if (haveCarrier)
  856.       {
  857.       strCpy(mess, "%s reports: ");
  858.       strCat(mess, RecBuf + 1);
  859.       no_good(mess, FALSE);
  860.  
  861.       }
  862.  
  863.     }
  864.   else
  865.     {
  866.     SendHostFile(fn->unambig);
  867.     if (haveCarrier)
  868.       {
  869.       sPrintf(msgBuf.mbtext, "%s sent to %s.", fn->unambig,
  870.       netBuf.netName);
  871.       netResult(msgBuf.mbtext);
  872.  
  873.       }
  874.  
  875.     }
  876.  
  877.   }
  878. extern FILE *upfd;
  879. /*
  880. * askFiles()
  881. *
  882. * This function will ask for file(s) from caller.
  883. */
  884. static void fl_req_free(struct fl_req *d);
  885. void askFiles()
  886.   {
  887.   label    data2;
  888.   SYS_FILE dataFl;
  889.   char     mess[130];
  890.   char     ambiguous;
  891.   int      result = ITL_SUCCESS;
  892.   FILE     *temp;
  893.   struct   cmd_data cmds;
  894.   struct   fl_req file_data, *list;
  895.   SListBase Failed =
  896.     {
  897.     NULL, NULL, NULL, fl_req_free, NULL
  898.  
  899.     };
  900.   extern char *READ_ANY, *WRITE_ANY;
  901.   if (!gotCarrier())
  902.     {
  903.     modStat = haveCarrier = FALSE;
  904.     return ;
  905.  
  906.     }
  907.   sPrintf(data2, "%d.rfl", thisNet);
  908.   makeSysName(dataFl, data2, &cfg.netArea);
  909.   temp = safeopen(dataFl, READ_ANY);
  910.   if (temp == NULL)
  911.     {
  912.     no_good("Couldn't open room request file for %s", FALSE);
  913.     netBuf.nbflags.room_files = FALSE;
  914.  
  915.     }
  916.   else
  917.     {
  918.     ITL_optimize(FALSE);    /* try for better protocol */
  919.     while ( result == ITL_SUCCESS &&
  920.     fread(&file_data, sizeof (file_data), 1, temp) == 1 &&
  921.     gotCarrier() && result == ITL_SUCCESS)
  922.       {
  923.       if (netSetNewArea(&file_data.flArea))
  924.         {
  925.         zero_struct(cmds);
  926.         ambiguous = !(strchr(file_data.roomfile, '*') == NULL &&
  927.         strchr(file_data.roomfile, '?') == NULL);
  928.         cmds.command = (!ambiguous) ? R_FILE_REQ : A_FILE_REQ;
  929.         strCpy(cmds.fields[0], file_data.room);
  930.         strCpy(cmds.fields[1], file_data.roomfile);
  931.         if( logNetResults )splitF(netLog, "Requesting %s in %s\n", file_data.roomfile,
  932.         file_data.room);
  933.         if (!sendNetCommand(&cmds,
  934.         (!ambiguous) ? "single file request" :
  935.         "multiple file request"))
  936.           {
  937.           sPrintf(mess, "%%s reports %s for file %s in %s.", RecBuf+1,
  938.           file_data.roomfile, file_data.room);
  939.           no_good(mess, FALSE);
  940.  
  941.           }
  942.         else
  943.           {
  944.           if (ambiguous)
  945.           result = multiReceive(&file_data);
  946.           else
  947.             {
  948.             if ((result = ITL_Receive(file_data.filename, FALSE,
  949.             TRUE, putFLChar, fclose)) == ITL_SUCCESS)
  950.               {
  951.               sPrintf(msgBuf.mbtext,
  952.               "File '%s' received from %s (stored in directory %s).",
  953.               file_data.filename, netBuf.netName,
  954.               prtNetArea(&file_data.flArea));
  955.               netResult(msgBuf.mbtext);
  956.  
  957.               }
  958.  
  959.             }
  960.  
  961.           }
  962.  
  963.         }
  964.       homeSpace();
  965.  
  966.       }
  967.     if (gotCarrier())
  968.       {
  969.       fclose(temp);
  970.       unlink(dataFl);
  971.       netBuf.nbflags.room_files = FALSE;
  972.  
  973.       }
  974.     else
  975.       {
  976.       haveCarrier = modStat = FALSE;
  977.       /* Now find out what we didn't get and set up a new request queue */
  978.       do
  979.         {
  980.         /* use do loop to get the one it failed in */
  981.         list = GetDynamic(sizeof *list);
  982.         copy_struct(file_data, (*list));
  983.         AddData(&Failed, list, NULL, FALSE);
  984.  
  985.         }
  986.       while (fread(&file_data, sizeof (file_data), 1, temp) == 1);
  987.       fclose(temp);
  988.       unlink(dataFl);
  989.       upfd = fopen(dataFl, WRITE_ANY);
  990.       KillList(&Failed);
  991.       fclose(upfd);
  992.  
  993.       }
  994.  
  995.     }
  996.  
  997.   }
  998. /*
  999. * fl_req_free()
  1000. *
  1001. * This will write and free a file request.
  1002. */
  1003. static void fl_req_free(struct fl_req *d)
  1004.   {
  1005.   if (upfd != NULL) fwrite(d, sizeof *d, 1, upfd);
  1006.   free(d);
  1007.  
  1008.   }
  1009. /*
  1010. * multiReceive()
  1011. *
  1012. * This function will receive multiple files.
  1013. */
  1014. char multiReceive(struct fl_req *file_data)
  1015.   {
  1016.   char        first = 1;
  1017.   extern char *WRITE_ANY;
  1018.   sPrintf(msgBuf.mbtext,
  1019.   "Following files received from %s in response to request for %s from %s: ",
  1020.   netBuf.netName, file_data->roomfile, file_data->room);
  1021.   do
  1022.     {
  1023.     if (ITL_Receive(NULL, FALSE, TRUE, putFLChar, fclose) != ITL_SUCCESS ||
  1024.     !gotCarrier()) return ITL_BAD_TRANS;
  1025.     if (RecBuf[0] == 0)
  1026.       {
  1027.       /* Last file name       */
  1028.       sPrintf(lbyte(msgBuf.mbtext), " (stored in directory %s).",
  1029.       prtNetArea(&file_data->flArea));
  1030.       netResult(msgBuf.mbtext);
  1031.       return ITL_SUCCESS;
  1032.  
  1033.       }
  1034.     if (!first)
  1035.     strCat(msgBuf.mbtext, ", ");
  1036.     else
  1037.     first = FALSE;
  1038.     strCat(msgBuf.mbtext, RecBuf);
  1039.     if (ITL_Receive(RecBuf, FALSE, TRUE, putFLChar, fclose) != ITL_SUCCESS
  1040.     || !gotCarrier()) return ITL_BAD_TRANS;
  1041.  
  1042.     }
  1043.   while (1);
  1044.   return ITL_SUCCESS;
  1045.  
  1046.   }
  1047. /*
  1048. * sendNetCommand()
  1049. *
  1050. * This sends a command to the receiver.
  1051. */
  1052. char sendNetCommand(struct cmd_data *cmds, char *error)
  1053.   {
  1054.   char errMsg[100];
  1055.   int  count;
  1056.   if (cfg.BoolFlags.debug && netDebug )
  1057.     {
  1058.     splitF(netLog, "Sending Command: %d\n", cmds->command);
  1059.     splitF(netLog, " Field[0]: %s\n", cmds->fields[0]);
  1060.     splitF(netLog, " Field[1]: %s\n", cmds->fields[1]);
  1061.     splitF(netLog, " Field[2]: %s\n", cmds->fields[2]);
  1062.     splitF(netLog, " Field[3]: %s\n", cmds->fields[3]);
  1063.     };
  1064.  
  1065.   if (!ITL_Send(STARTUP))
  1066.     {
  1067.     sPrintf(errMsg, "Link failure for %s (system: %%s).", error);
  1068.     if (cmds->command != HANGUP) no_good(errMsg, TRUE);
  1069.     killConnection();
  1070.     return FALSE;
  1071.  
  1072.     }
  1073.   sendITLchar(cmds->command);
  1074.   for (count = 0; count < 4; count++)
  1075.     {
  1076.     if (cmds->fields[count][0])
  1077.       {
  1078.       mTrPrintf("%s", cmds->fields[count]);
  1079.  
  1080.       }
  1081.  
  1082.     }
  1083.   sendITLchar(0);
  1084.   ITL_Send(FINISH);
  1085.   if (cmds->command == HANGUP && !inReceive) return TRUE;
  1086.   ITL_Receive(NULL, FALSE, TRUE, putFLChar, fclose);
  1087.   if (RecBuf[0] == BAD || !gotCarrier()) return FALSE;
  1088.   return TRUE;
  1089.  
  1090.   }
  1091. /*
  1092. * sendHangUp()
  1093. *
  1094. * This sends the hangup command to receiver.
  1095. */
  1096. void sendHangUp()
  1097.   {
  1098.   struct cmd_data cmds;
  1099.   if (!gotCarrier())
  1100.     {
  1101.     modStat = haveCarrier = FALSE;
  1102.     return ;
  1103.  
  1104.     }
  1105.   zero_struct(cmds);
  1106.   cmds.command = HANGUP;
  1107.   sendNetCommand(&cmds, "HANGUP");
  1108.  
  1109.   }
  1110. /*
  1111. * no_good()
  1112. *
  1113. * This handles error messages when something really bad happens.
  1114. */
  1115. void no_good(char *str, char hup)
  1116.   {
  1117.   sPrintf(msgBuf.mbtext, str, netBuf.netName);
  1118.   if (hup)
  1119.     {
  1120.     killConnection();
  1121.  
  1122.     }
  1123.   netResult(msgBuf.mbtext);
  1124.  
  1125.   }
  1126. /*
  1127. * s_m_n()
  1128. *
  1129. * This sends mail normal (non-route mail).
  1130. */
  1131. int s_m_n()
  1132.   {
  1133.   FILE     *ptrs;
  1134.   label    fntemp;
  1135.   SYS_FILE fn;
  1136.   int      messCount = 0;
  1137.   struct   netMLstruct buf;
  1138.   extern char *READ_ANY;
  1139.   sPrintf(fntemp, "%d.ml", thisNet);
  1140.   makeSysName(fn, fntemp, &cfg.netArea);
  1141.   if ((ptrs = safeopen(fn, READ_ANY)) == NULL)
  1142.     {
  1143.     if (netBuf.nbflags.normal_mail)
  1144.       {
  1145.       sPrintf(msgBuf.mbtext, "No mail file to send to %s?",
  1146.       netBuf.netName);
  1147.       netResult(msgBuf.mbtext);
  1148.  
  1149.       }
  1150.     return 0;
  1151.  
  1152.     }
  1153.   while (getMLNet(ptrs, buf) && TrError == TRAN_SUCCESS)
  1154.     {
  1155.     if (findMessage(buf.ML_loc, buf.ML_id, TRUE))
  1156.       {
  1157.       if (netDebug)
  1158.         {
  1159.         MessageBuffer *msg = &msgBuf;
  1160.         splitF(netLog, "Message %6d Sector ID: %6d Author:%s\n",  msg->mbheadChar, msg->mbheadSector, msg->mbauth);
  1161.         splitF(netLog, "Date:%20s Time:%20s Local Id:%20s\n",  msg->mbdate,  msg-> mbtime,  msg-> mbId);
  1162.         splitF(netLog, "Human:%20s ID:%20s Room:%20s\n",  msg->mboname,  msg->mborig,  msg->mbroom);
  1163.         splitF(netLog, "Origin:%20s To:%20s\n",  msg->mbsrcId,  msg->mbto);
  1164.         splitF(netLog, "Route:%s\n", msg->mbaddr);
  1165.         splitF(netLog, "OtherNet:%s\n",msg->mbOther);
  1166.         splitF(netLog, "reply:%20s Domain:%20s\n",msg->mbreply, msg->mbdomain);
  1167.         }
  1168.       prNetStyle(0, sendITLchar, TRUE, netBuf.netName);
  1169.       messCount++;
  1170.  
  1171.       }
  1172.  
  1173.     }
  1174.   fclose(ptrs);
  1175.   if (TrError == TRAN_SUCCESS)
  1176.     {
  1177.     unlink(fn);
  1178.     return messCount;
  1179.  
  1180.     }
  1181.   killConnection();
  1182.   if( logNetResults )splitF(netLog, "\nFailed transferring mail!\n");
  1183.   return 0;
  1184.  
  1185.   }
  1186. /*
  1187. * SendHostFile()
  1188. *
  1189. * This function will send a file to the other system.
  1190. */
  1191. void SendHostFile(char *fn)
  1192.   {
  1193.   int  success;
  1194.   FILE *fd;
  1195.   extern int errno;
  1196.   extern char *READ_ANY;
  1197.   success = ((fd = safeopen(fn, READ_ANY)) != NULL);
  1198.   if (ITL_Send(STARTUP))
  1199.     {
  1200.     if (!success) mTrPrintf("System error failure, this is a bogus file.");
  1201.     else
  1202.       {
  1203.       SendThatDamnFile(fd, sendITLchar);
  1204.  
  1205.       }
  1206.     ITL_Send(FINISH);
  1207.  
  1208.     }
  1209.   if (!success)
  1210.     {
  1211.     sPrintf(msgBuf.mbtext, "System error! Couldn't open %s for %s, errno %d.",
  1212.     fn, netBuf.netName, errno);
  1213.     netResult(msgBuf.mbtext);
  1214.  
  1215.     }
  1216.  
  1217.   }
  1218.